﻿//-----------------------------------------------------------------------
// <copyright file="Identity.cs" company="FastNET Services">
//     Copyright (c) 2008-2009. All Rights Reserved.
// </copyright>
// <license>
//     GPLv2
// </license>
// <warranty>
//     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
//     BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </warranty>
//-----------------------------------------------------------------------
//Code can be found in the GateShift project too: http://gateshift.codeplex.com
#region Usings

using System;

#endregion

// DEV NOTES:
/* Should the following be implemented?
 * 
 * IComparable(T)
 * */

namespace FastNET.CleanAct.Common.Repository
{
    /// <summary>
    /// Generic Identification class for operations without exposing the real identifyable object type
    /// </summary>
    public struct Identity : IConvertible, IEquatable<short>, IEquatable<int>, IEquatable<long>, IEquatable<Guid>, IEquatable<Identity>
    {
        #region Real Storage

        private readonly ValueType _value;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the Identity struct
        /// </summary>
        /// <param name="value">Value to store the Identity as</param>
        public Identity(short value)
            : this()
        {
            _value = value;
        }

        /// <summary>
        /// Initializes a new instance of the Identity struct
        /// </summary>
        /// <param name="value">Value to store the Identity as</param>
        public Identity(int value)
            : this()
        {
            _value = value;
        }

        /// <summary>
        /// Initializes a new instance of the Identity struct
        /// </summary>
        /// <param name="value">Value to store the Identity as</param>
        public Identity(long value)
            : this()
        {
            _value = value;
        }

        /// <summary>
        /// Initializes a new instance of the Identity struct
        /// </summary>
        /// <param name="value">Value to store the Identity as</param>
        public Identity(Guid value)
            : this()
        {
            _value = value;
        }

        #endregion

        #region Operators

        #region Identity to Identity

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(Identity Left, Identity Right)
        {
            return Equals(Left, Right);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(Identity Left, Identity Right)
        {
            return !Equals(Left, Right);
        }

        #endregion

        #region Int16 to Identity

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Int16 to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(short Left, Identity Right)
        {
            return Right.Equals(Left);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Int16 to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(short Left, Identity Right)
        {
            return !Right.Equals(Left);
        }

        #endregion

        #region Identity to Int16

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Int16 to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(Identity Left, short Right)
        {
            return Left.Equals(Right);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Int16 to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(Identity Left, short Right)
        {
            return !Left.Equals(Right);
        }

        #endregion

        #region Int32 to Identity

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Int32 to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(int Left, Identity Right)
        {
            return Right.Equals(Left);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Int32 to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(int Left, Identity Right)
        {
            return !Right.Equals(Left);
        }

        #endregion

        #region Identity to Int32

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Int32 to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(Identity Left, int Right)
        {
            return Left.Equals(Right);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Int32 to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(Identity Left, int Right)
        {
            return !Left.Equals(Right);
        }

        #endregion

        #region Int64 to Identity

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Int64 to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(long Left, Identity Right)
        {
            return Right.Equals(Left);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Int64 to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(long Left, Identity Right)
        {
            return !Right.Equals(Left);
        }

        #endregion

        #region Identity to Int64

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Int64 to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(Identity Left, long Right)
        {
            return Left.Equals(Right);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Int64 to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(Identity Left, long Right)
        {
            return !Left.Equals(Right);
        }

        #endregion

        #region Guid to Identity

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Guid to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(Guid Left, Identity Right)
        {
            return Right.Equals(Left);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Int16 to compare with</param>
        /// <param name="Right">Identity to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(Guid Left, Identity Right)
        {
            return !Right.Equals(Left);
        }

        #endregion

        #region Identity to Guid

        /// <summary>
        /// Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Guid to compare to</param>
        /// <returns>Boolean whether or not the Identities are equal</returns>
        public static bool operator ==(Identity Left, Guid Right)
        {
            return Left.Equals(Right);
        }

        /// <summary>
        /// Non-Equality Operator for handling Identities with the internal value
        /// </summary>
        /// <param name="Left">Identity to compare with</param>
        /// <param name="Right">Guid to compare to</param>
        /// <returns>Boolean whether or not the Identities are not equal</returns>
        public static bool operator !=(Identity Left, Guid Right)
        {
            return !Left.Equals(Right);
        }

        #endregion

        #endregion

        #region Implicit Operators

        /// <summary>
        /// Converts an Int64 into an Identity
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Identity created from the value</returns>
        public static implicit operator Identity(long value)
        {
            return new Identity(value);
        }

        /// <summary>
        /// Converts an Int32 into an Identity
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Identity created from the value</returns>
        public static implicit operator Identity(int value)
        {
            return new Identity(value);
        }

        /// <summary>
        /// Converts an Int16 into an Identity
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Identity created from the value</returns>
        public static implicit operator Identity(short value)
        {
            return new Identity(value);
        }

        /// <summary>
        /// Converts an Guid into an Identity
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Identity created from the value</returns>
        public static implicit operator Identity(Guid value)
        {
            return new Identity(value);
        }

        /// <summary>
        /// Converts an Int64 into an Identity
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Identity created from the value</returns>
        public static implicit operator long(Identity value)
        {
            return Convert.ToInt64(value._value);
        }

        /// <summary>
        /// Converts an Int32 into an Identity
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Identity created from the value</returns>
        public static implicit operator int(Identity value)
        {
            return Convert.ToInt32(value._value);
        }

        /// <summary>
        /// Converts an Int16 into an Identity
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Identity created from the value</returns>
        public static implicit operator short(Identity value)
        {
            return Convert.ToInt16(value._value);
        }

        /// <summary>
        /// Converts an Guid into an Identity
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Identity created from the value</returns>
        public static implicit operator Guid(Identity value)
        {
            return (Guid)value._value;
        }

        #endregion

        #region Parsing

        /// <summary>
        /// Static method for trying to parse a value into a valid Identity
        /// </summary>
        /// <param name="Value">Value to try and parse</param>
        /// <param name="ParsedValue">Identity with the value requested (OUT)</param>
        /// <returns>Boolean based on the success of the parsing</returns>
        /// <exception cref="ArgumentNullException">Thrown if Value is null or empty</exception>
        public static bool TryParse(string Value, out Identity? ParsedValue)
        {
            // Initialize outputs
            ParsedValue = null;

            if (string.IsNullOrEmpty(Value))
            {
                throw new ArgumentNullException("Value", "Cannot try parsing with a null or empty value");
            }

            // Try short 
            short tempInt16;
            if (Int16.TryParse(Value, out tempInt16))
            {
                ParsedValue = new Identity(tempInt16);
                return true;
            }

            // Try int
            int tempInt32;
            if (int.TryParse(Value, out tempInt32))
            {
                ParsedValue = new Identity(tempInt32);
                return true;
            }

            // Try Int64
            long tempInt64;
            if (Int64.TryParse(Value, out tempInt64))
            {
                ParsedValue = new Identity(tempInt64);
                return true;
            }

            // Try Guid
            try
            {
                ParsedValue = new Identity(new Guid(Value));
                return true;
            }
            catch (FormatException)
            {
            }
            catch (OverflowException)
            {
            }
            catch (ArgumentNullException)
            {
            }

            // Nothing else works so return false;
            return false;
        }

        /// <summary>
        /// Static method to parse a value into an Identity
        /// </summary>
        /// <param name="Value">Value to parse</param>
        /// <returns>Identity parsed from the text value</returns>
        /// <exception cref="ArgumentNullException">Thrown if Value is null or empty</exception>
        /// <exception cref="InvalidCastException">Thrown if Value is not a valid Identity</exception>
        public static Identity Parse(string Value)
        {
            Identity? newIdentity;

            if (string.IsNullOrEmpty(Value))
            {
                throw new ArgumentNullException("Value", "Cannot force a parsing with a null or empty value");
            }

            if (!TryParse(Value, out newIdentity))
            {
                throw new InvalidCastException("Value cannot be converted to an Identity");
            }

            return newIdentity.Value;
        }

        #endregion

        #region Object Basics

        /// <summary>
        /// Overridden method to handle equality operations for the Identity object
        /// </summary>
        /// <param name="o">Object to compare values to</param>
        /// <returns>Boolean whether or not the object passed in is equal to the current object</returns>
        public override bool Equals(object o)
        {
            if (o == null && _value != null)
            {
                return false;
            }

            if (o == null && _value == null)
            {
                return true;
            }

            // If the object is another identity, then use the value of it.
            if (o is Identity)
            {
                return _value.Equals(((Identity)o)._value);
            }

            // Otherwise compare passed in object to the stored value
            // Validate types first
            if (o != null)
            {
                return o.GetType() == _value.GetType() && _value.Equals(o);
            }

            return false;
        }

        /// <summary>
        /// Returns the hash code for this identity
        /// </summary>
        /// <returns>Int32 with the class' hash code</returns>
        public override int GetHashCode()
        {
            return ToString().GetHashCode();
        }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other"> An object to compare with this object. </param>
        /// <returns> True if the current object is equal to the <paramref name="other" /> parameter; otherwise, false. </returns>
        bool IEquatable<short>.Equals(short other)
        {
            return Equals(other);
        }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other"> An object to compare with this object. </param>
        /// <returns> True if the current object is equal to the <paramref name="other" /> parameter; otherwise, false. </returns>
        bool IEquatable<int>.Equals(int other)
        {
            return Equals(other);
        }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other"> An object to compare with this object. </param>
        /// <returns> True if the current object is equal to the <paramref name="other" /> parameter; otherwise, false. </returns>
        bool IEquatable<long>.Equals(long other)
        {
            return Equals(other);
        }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other"> An object to compare with this object. </param>
        /// <returns> True if the current object is equal to the <paramref name="other" /> parameter; otherwise, false. </returns>
        bool IEquatable<Guid>.Equals(Guid other)
        {
            return Equals(other);
        }

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other"> An object to compare with this object. </param>
        /// <returns> True if the current object is equal to the <paramref name="other" /> parameter; otherwise, false. </returns>
        bool IEquatable<Identity>.Equals(Identity other)
        {
            return Equals(other);
        }

        /// <summary>
        /// Returns a tring for the actual identity
        /// </summary>
        /// <returns>String representing the internal value or this object</returns>
        public override string ToString()
        {
            return _value == null ? GetType().ToString() : _value.ToString();
        }

        #endregion

        #region Checks

        /// <summary>
        /// Checks to see if the value is a valid type for operations
        /// </summary>
        /// <returns>A value indicating whether or not the internal value can be of long type</returns>
        public bool CanFitInInt64()
        {
            return _value is long || _value is int || _value is short;
        }

        /// <summary>
        /// Checks to see if the value is a valid type for operations
        /// </summary>
        /// <returns>A value indicating whether or not the internal value can be of int type</returns>
        public bool CanFitInInt32()
        {
            return _value is int || _value is short;
        }

        /// <summary>
        /// Checks to see if the value is a valid type for operations
        /// </summary>
        /// <returns>A value indicating whether or not the internal value can be of short type</returns>
        public bool CanFitInInt16()
        {
            return _value is short;
        }

        /// <summary>
        /// Checks to see if the value is a valid type for operations
        /// </summary>
        /// <returns>A value indicating whether or not the internal value can be of guid type</returns>
        public bool CanFitInGuid()
        {
            return _value is Guid;
        }

        #endregion

        /// <summary>
        /// Checks the internal value to see if it matches the specified type
        /// </summary>
        /// <param name="typeToCheck">Type to check against</param>
        /// <returns>Boolean whether or not the type matches</returns>
        public bool IsInternalType(Type typeToCheck)
        {
            return _value.GetType() == typeToCheck;
        }

        /// <summary>
        /// Gets the Type for the underlying value
        /// </summary>
        /// <returns>Type for the underlying value</returns>
        public Type UnderlyingType()
        {
            return _value.GetType();
        }

        #region Implementation of IConvertible

        /// <summary>
        /// Returns the <see cref="T:System.TypeCode" /> for this instance.
        /// </summary>
        /// <returns> The enumerated constant that is the <see cref="T:System.TypeCode" /> of the class or value type that implements this interface. </returns>
        TypeCode IConvertible.GetTypeCode()
        {
            return ((IConvertible)_value).GetTypeCode();
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent Boolean value using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> A Boolean value equivalent to the value of this instance. </returns>
        bool IConvertible.ToBoolean(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToBoolean(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent Unicode character using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> A Unicode character equivalent to the value of this instance. </returns>
        char IConvertible.ToChar(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToChar(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent 8-bit signed integer using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An 8-bit signed integer equivalent to the value of this instance. </returns>
        sbyte IConvertible.ToSByte(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToSByte(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent 8-bit unsigned integer using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An 8-bit unsigned integer equivalent to the value of this instance. </returns>
        byte IConvertible.ToByte(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToByte(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent 16-bit signed integer using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider">An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An 16-bit signed integer equivalent to the value of this instance. </returns>
        short IConvertible.ToInt16(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToInt16(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent 16-bit unsigned integer using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An 16-bit unsigned integer equivalent to the value of this instance. </returns>
        ushort IConvertible.ToUInt16(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToUInt16(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent 32-bit signed integer using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An 32-bit signed integer equivalent to the value of this instance. </returns>
        int IConvertible.ToInt32(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToInt32(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent 32-bit unsigned integer using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An 32-bit unsigned integer equivalent to the value of this instance. </returns>
        uint IConvertible.ToUInt32(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToUInt32(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent 64-bit signed integer using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An 64-bit signed integer equivalent to the value of this instance. </returns>
        long IConvertible.ToInt64(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToInt64(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent 64-bit unsigned integer using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An 64-bit unsigned integer equivalent to the value of this instance. </returns>
        ulong IConvertible.ToUInt64(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToUInt64(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent single-precision floating-point number using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> A single-precision floating-point number equivalent to the value of this instance. </returns>
        float IConvertible.ToSingle(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToSingle(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent double-precision floating-point number using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> A double-precision floating-point number equivalent to the value of this instance. </returns>
        double IConvertible.ToDouble(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToDouble(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent <see cref="T:System.Decimal" /> number using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> A <see cref="T:System.Decimal" /> number equivalent to the value of this instance. </returns>
        decimal IConvertible.ToDecimal(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToDecimal(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent <see cref="T:System.DateTime" /> using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> A <see cref="T:System.DateTime" /> instance equivalent to the value of this instance. </returns>
        DateTime IConvertible.ToDateTime(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToDateTime(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an equivalent <see cref="T:System.String" /> using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> A <see cref="T:System.String" /> instance equivalent to the value of this instance. </returns>
        string IConvertible.ToString(IFormatProvider provider)
        {
            return ((IConvertible)_value).ToString(provider);
        }

        /// <summary>
        /// Converts the value of this instance to an <see cref="T:System.Object" /> of the specified <see cref="T:System.Type" /> that has an equivalent value, using the specified culture-specific formatting information.
        /// </summary>
        /// <param name="conversionType"> The <see cref="T:System.Type" /> to which the value of this instance is converted. </param>
        /// <param name="provider"> An <see cref="T:System.IFormatProvider" /> interface implementation that supplies culture-specific formatting information. </param>
        /// <returns> An <see cref="T:System.Object" /> instance of type <paramref name="conversionType" /> whose value is equivalent to the value of this instance. </returns>
        object IConvertible.ToType(Type conversionType, IFormatProvider provider)
        {
            return ((IConvertible)_value).ToType(conversionType, provider);
        }

        #endregion
    }
}